include("caf_core/shared/RD2_Tools.lua")
RD2Ents = {}


function RD2Ents.MakeEnt( tool, ply, Ang, Pos, class, type, sub_type, model, frozen, Extra_Data, Data )
	
	if tool.AdminOnly and not ply:IsAdmin() then return false end
	if tool.Renamed then
		if class and tool.Renamed.class and tool.Renamed.class[class] then
			class = tool.Renamed.class[class]
		end
		if type and tool.Renamed.type and tool.Renamed.type[type] then
			type = tool.Renamed.type[type]
		end
		if sub_type and tool.Renamed.sub_type and tool.Renamed.sub_type[sub_type] then
			sub_type = tool.Renamed.sub_type[sub_type]
		end
	end
	
	type = type or class
	if !type or !(sub_type or model) then return false end
	
	local devinfo
	if !sub_type and tool.Devices[type] and tool.Devices[type].models and tool.Devices[type].models[model] then
		devinfo = tool.Devices[type].models[model]
		sub_type = devinfo.sub_type
	elseif tool.Devices[type] and tool.Devices[type].devices[sub_type] then
		devinfo = tool.Devices[type].devices[sub_type]
		if model and devinfo.model != model then
			CAF.WriteToDebugFile("caf_tool_error", "CAF: model passed does not match what is defined for this device\n")
		end
	else
		CAF.WriteToDebugFile("caf_tool_error", "CAF: Invalid Device Info! class:"..tostring(class).." type:"..tostring(type).." sub_type:"..tostring(sub_type))
		return false
	end
	--allow for overrides of old data
	type		= devinfo.type
	sub_type	= devinfo.sub_type
	class		= devinfo.class
	model		= devinfo.model
	
	if !util.IsValidModel(model) or !util.IsValidProp(model) then return false end
	
	
	local ent
	if (devinfo.group.AdminOnly or devinfo.AdminOnly) and not ply:IsAdmin() then return false end
	if devinfo.group.MakeFunc then
		ent = devinfo.group.MakeFunc(tool, ply, Ang, Pos, class, type, sub_type, model, frozen, Extra_Data, devinfo)
		if IsValid(ent) then return false end
		if devinfo.group.MakeFuncReturn then return ent end
	else
		ent = ents.Create(class)
		if !ent:IsValid() then return false end
			ent:SetModel(model)
			ent:SetAngles(Ang)
			ent:SetPos(Pos)
			ent:SetPlayer(ply)
		ent:Spawn() --run ENT:Initialize()
		ent:Activate()
		
		duplicator.DoGenericPhysics(ent, ply, Data)
		
	end
	
	local mass				= devinfo.mass or 0
	local maxhealth			= devinfo.maxhealth or 0
	local ent_extras		= devinfo.ent_extras or {}
	ent_extras.type			= type
	ent_extras.sub_type		= sub_type
	ent_extras.Extra_Data	= Extra_Data
	
	if devinfo.group.func then
		mass, maxhealth = devinfo.group.func( ent, type, sub_type, devinfo, Extra_Data, ent_extras )
	end
	
	if devinfo.func  then
		mass, maxhealth = devinfo.func( ent, type, sub_type, devinfo, Extra_Data, ent_extras )
	end
	
	if devinfo.group.func or devinfo.func then
		mass		= mass or devinfo.mass or 0
		maxhealth	= maxhealth or devinfo.maxhealth or 0
	end
	
	if devinfo.res then
		for res,amt in pairs(devinfo.res) do
			local RD = CAF.GetAddon("Resource Distribution")
			if RD then
				RD.AddResource(ent, res, amt)
			end
		end
	end
	
	if devinfo.skin then		ent:SetSkin(devinfo.skin) end
	if devinfo.material then	ent:SetMaterial(devinfo.material) end
	if ent.Setup then			ent:Setup(Extra_Data) end
	
	
	if maxhealth > 0 then
		ent:SetHealth( maxhealth )
		ent:SetMaxHealth( maxhealth )
	else
		ent:SetHealth( 1 )
		ent:SetMaxHealth( 0 )
	end
	
	table.Merge(ent:GetTable(), ent_extras )
	
	if mass > 0 or frozen then
		local phys = ent:GetPhysicsObject()
		if phys:IsValid() then
			if mass > 0 then
				phys:SetMass(mass)
				phys:Wake()
			end
			if frozen then
				phys:EnableMotion(false) 
				ply:AddFrozenPhysicsObject(ent, phys)
			end
		end
	end
	
	return ent
end

--TAD2020: duplicator support
--build the DupeInfo table and save it as an entity mod
--[[function RD_BuildDupeInfo( ent )
	if (!ent.resources2) then return end
	
	local info = {}
	info.devices = {}
	
	local beamtable = RDbeamlib.GetBeamTable( ent )
	info.beams = {}
	
	for ent2ID, ent2 in pairs( ent.resources2links ) do
		if ( ent2 and ent2:IsValid() ) then 
			table.insert(info.devices, ent2ID)
			
			if beamtable[ent2] then
				info.beams[ent2ID] = beamtable[ent2]
			end
		end
	end
	
	if info.devices then
		duplicator.StoreEntityModifier( ent, "RDDupeInfo", info )
	end
	
end

--apply the DupeInfo
function RD_ApplyDupeInfo( ent, CreatedEntities )
	if (ent.EntityMods) and (ent.EntityMods.RDDupeInfo) and (ent.EntityMods.RDDupeInfo.devices) then
		
		local RDDupeInfo = ent.EntityMods.RDDupeInfo
		
		for _,ent2ID in pairs(RDDupeInfo.devices) do
			local ent2 = CreatedEntities[ ent2ID ]
			
			if ent2 and ent2:IsValid() then
				
				if (RDDupeInfo.beams) and (RDDupeInfo.beams[ ent2ID ]) then
					Dev_Link(
						ent, ent2, 
						RDDupeInfo.beams[ ent2ID ].start_pos, 
						RDDupeInfo.beams[ ent2ID ].dest_pos, 
						RDDupeInfo.beams[ ent2ID ].material, 
						RDDupeInfo.beams[ ent2ID ].color, 
						RDDupeInfo.beams[ ent2ID ].width
					)
				else
					Dev_Link(ent, ent2)
				end
			end
		end
		
		ent.EntityMods.RDDupeInfo = nil --trash this info, we'll never need it again
		
	end
end]]--


function RD2Ents.RegDupeFunction( class, MakeFunc )
	duplicator.RegisterEntityClass( class, MakeFunc, "Ang", "Pos", "Class", "type", "sub_type", "Model", "frozen", "Extra_Data", "Data" )
end




